#include "CameraWidget.h"

#include <QCamera>
#include <QCameraInfo>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPaintEvent>
#include <QVBoxLayout>

FrameGrabber::FrameGrabber(QObject* parent)
    : QAbstractVideoSurface(parent)
{
}

bool FrameGrabber::present(const QVideoFrame& frame)
{
    if (frame.isValid()) {
        QVideoFrame cloneFrame(frame);
        cloneFrame.map(QAbstractVideoBuffer::ReadOnly);

        QImage image(cloneFrame.bits(), cloneFrame.width(), cloneFrame.height(),
            QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));

        emit frameAvailable(image.copy()); //发送给graphicsView显示

        cloneFrame.unmap();
        return true;
    }

    return false;
}

QList<QVideoFrame::PixelFormat> FrameGrabber::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
    Q_UNUSED(handleType);
    return QList<QVideoFrame::PixelFormat>()
        << QVideoFrame::Format_ARGB32
        << QVideoFrame::Format_ARGB32_Premultiplied
        << QVideoFrame::Format_BGRA32
        << QVideoFrame::Format_BGRA32_Premultiplied
        << QVideoFrame::Format_RGB32
        << QVideoFrame::Format_RGB24;
}

// class CameraCapture
//

CameraWidget::CameraWidget(QWidget* parent)
    : QWidget(parent)
{
    graphicsView = new QGraphicsView(this);
    graphicsScene = new QGraphicsScene(this);
    graphicsView->setScene(graphicsScene);
    pixmapItem = new QGraphicsPixmapItem();
    graphicsScene->addItem(pixmapItem);
    graphicsView->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); // 抗锯齿

    // 布局

    QVBoxLayout* mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(graphicsView);

    setLayout(mainLayout);

    frameGrabber = new FrameGrabber(this);
    connect(frameGrabber, &FrameGrabber::frameAvailable, this, [=](const QImage& image) {
        QPixmap pixmap = QPixmap::fromImage(image);
        pixmapItem->setPixmap(pixmap);
        // 设置 pixmapItem 的缩放模式，确保图像适应 scene
        pixmapItem->setTransformationMode(Qt::SmoothTransformation); // 保证缩放质量
        //        graphicsScene->setSceneRect(pixmap.rect()); // 调整scene大小
        graphicsView->fitInView(graphicsScene->sceneRect(), Qt::KeepAspectRatio); // 保持纵横比
    });
}

bool CameraWidget::isOpened()
{
    if (m_camera) {
        return m_camera->status() == QCamera::Status::ActiveStatus;
    }
    return false;
}

void CameraWidget::setErrorMessage(const QString& message)
{
    if (!message.isEmpty())
        m_dev = "";
    m_errorMessage = message;
}

void CameraWidget::paintEvent(QPaintEvent* event)
{
    QWidget::paintEvent(event);

    if (!m_errorMessage.isEmpty()) {
        QPainter painter(this); // 在 widget  上绘制
        painter.setBrush(Qt::black); // 黑色背景
        painter.setPen(Qt::white); // 白色字体
        painter.drawRect(graphicsView->geometry()); // 绘制在 graphicsView 的区域

        painter.setFont(QFont("Arial", 20));
        painter.drawText(graphicsView->geometry(), Qt::AlignCenter, m_errorMessage);
    }
}

void CameraWidget::open(QString dev)
{
    if (m_camera) {
        m_camera->stop(); // 停止之前的摄像头
        disconnect(m_camera, nullptr, this, nullptr); // 断开所有信号槽
        delete m_camera;
        m_camera = nullptr;
    }

    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    foreach (const QCameraInfo& cameraInfo, cameras) {
        if (cameraInfo.deviceName() == dev) {
            m_camera = new QCamera(cameraInfo);
            m_camera->setViewfinder(frameGrabber);
            QCameraViewfinderSettings settings;
            settings.setResolution(1920, 1080);
            m_camera->setViewfinderSettings(settings);
            m_dev = dev;
        }
    }

    if (!m_camera) {
        qDebug() << "new camera failed";
        return;
    }

    // 处理错误信号
    connect(m_camera, QOverload<QCamera::Error>::of(&QCamera::error),
        [this](QCamera::Error error) {
            qDebug() << "Camera error:" << error;
            switch (error) {
            case QCamera::Error::NoError:
                break;
            case QCamera::Error::CameraError:
                setErrorMessage("相机错误，请检查");
                break;
            case QCamera::Error::ServiceMissingError:
                setErrorMessage("相机服务缺失");
                break;
            case QCamera::Error::NotSupportedFeatureError:
                setErrorMessage("该功能不支持");
                break;
            case QCamera::Error::InvalidRequestError:
                setErrorMessage("权限不足，请检查应用权限");
                break;
            }
            update(); // 强制重绘，显示错误信息
        });

    connect(m_camera, &QCamera::statusChanged, this, [this](QCamera::Status status) {
        qDebug() << "Camera status changed:" << status;
        if (status == QCamera::Status::UnloadedStatus) {
            setErrorMessage("摄像头未加载");
            update();
        } else {
            setErrorMessage(""); // 清空错误信息
            update();
        }
    });

    m_camera->start();

    if (m_camera->status() != QCamera::ActiveStatus) {
        // 摄像头启动失败，显示错误信息.  可以不需要，error信号一般能覆盖
    } else {
        m_errorMessage = "";
    }
}

void CameraWidget::close()
{
    if (m_camera)
        m_camera->stop();
}

void CameraWidget::setMirrored(bool enable)
{
    QTransform transform;
    if (enable) {
        transform.scale(-1, 1); // 水平翻转
        transform.translate(-graphicsScene->width(), 0); // 调整位置
    }
    pixmapItem->setTransform(transform);
}

QString CameraWidget::getDevPath()
{
    return m_dev;
}

// class ViewFinder
//

//ViewFinder::ViewFinder(QWidget* parent)
//    : QGraphicsView(parent)
//{
//    scene = new QGraphicsScene(this);
//    setScene(scene);
//    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 禁用水平滚动条
//    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 禁用垂直滚动条
//    mirror = false;
//}

//void ViewFinder::setImage(const QImage& image)
//{
//    currentImage = image;
//    updateScene();
//}

//void ViewFinder::setMirror(bool mirrorEnabled)
//{
//    mirror = mirrorEnabled;
//    updateScene();
//}

//void ViewFinder::updateScene()
//{
//    scene->clear(); // 清空 scene，否则画面会重叠
//    QPixmap pixmap = QPixmap::fromImage(currentImage);

//    if (mirror) {
//        pixmap = pixmap.transformed(QTransform().scale(-1, 1)); // 水平翻转
//    }

//    scene->addPixmap(pixmap);
//    fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio); // 保持宽高比
//}

//void ViewFinder::resizeEvent(QResizeEvent* event)
//{
//    QGraphicsView::resizeEvent(event);
//    fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
//}
